#pragma once

#include "Socket.hpp"
#include "signal.h"
#include <functional>
#include <unistd.h>

// int ForkNum = 10;
using func_t = function<std::string(std::string &pakeage)>;
class TcpServer
{
public:
    TcpServer()
    {
    }

    TcpServer(const uint16_t &port, func_t callback) : _port(port), _callback(callback)
    {
    }

    void Serverinit()
    {
        _sk.Socket();
        _sk.Bind(_port);
        _sk.Listen();

        lg(INFO, "Network connection successful!!!");
    }

    void start()
    {
        // _sk.Close();
        signal(SIGCLD, SIG_IGN);
        signal(SIGPIPE, SIG_IGN);

        while (true)
        {
            std::string clientip;
            uint16_t clientport;

            int sockfd = _sk.Accept(&clientport, &clientip);
            // 连接失败继续连接下一个
            if (sockfd < 0)
            {
                lg(WARNING, "connect fail.. Trying to connect");
                continue;
            }
            // 对端主机信息
            std::cout << "clientip: " << clientip << " " << "clientport: " << clientport << std::endl;

            std::string inbuffer_stream;
            if (fork() == 0) // 让子进程进行服务
            {
                _sk.Close();
                // std::cout << "fork create process success!!!" << std::endl;
                char inbuffer[1024];
                while (true)
                {
                    ssize_t n = read(sockfd, inbuffer, sizeof(inbuffer) - 1);
                    // std::cout << "read success!!!" << std::endl;

                    if (n > 0)
                    {
                        inbuffer[n] = 0;
                        inbuffer_stream = inbuffer;

                        while (true)
                        {
                            std::string info = _callback(inbuffer_stream); // 需要将数据序列化
                            // 客户端向服务器发送的可能不不是一个完整的数据，如果不是就一直等待，直到收到完整的数据
                            if (info.empty())
                                break; // 没有数据直接退出

                            lg(DEBUG, "%s", inbuffer_stream.c_str());
                            lg(DEBUG, "%s", info.c_str());

                            // 将处理后的数据传给对端主机
                            write(sockfd, info.c_str(), info.size());
                            // std::cout << "write success!!!" << std::endl;
                        }
                    }
                    else if (n == 0)
                    {
                        break;
                    }
                    else
                    {
                        break;
                    }
                }
                exit(0);
            }
            close(sockfd);
        }
    }

    ~TcpServer()
    {
    }

private:
    Sock _sk;       // 创建监听套接字
    uint16_t _port; // 端口号
    func_t _callback;
};